package com.yl.plugin.util;

import com.yl.plugin.method.base.BaseMethod;
import com.yl.plugin.model.AdditionalProperty;
import com.yl.plugin.model.LombokProperty;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.stream.Streams;
import org.mybatis.generator.config.Context;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 工具类
 *
 * @author:liuxubo
 * @date:2023/7/12 16:27
 */
public class Util {
    /**
     * 获取配置的属性并赋值给MbgProperty对象
     *
     * @param properties
     * @param context
     */
    public static AdditionalProperty setMbgProperty(Properties properties, Context context) {
        Boolean enableSwagger2 = Boolean.valueOf(context.getProperty("enableSwagger2"));
        Boolean enableSelectSelective = Boolean.valueOf(properties.getProperty("enableSelectSelective", "false"));
        Boolean enableService = Boolean.valueOf(properties.getProperty("enableService", "false"));
        String serviceTargetProject = properties.getProperty("serviceTargetProject");
        String servicePackage = properties.getProperty("servicePackage");
        String serviceImplTargetProject = properties.getProperty("serviceImplTargetProject");
        String serviceImplPackage = properties.getProperty("serviceImplPackage");
        Boolean enableController = Boolean.valueOf(properties.getProperty("enableController", "false"));
        String controllerTargetProject = properties.getProperty("controllerTargetProject");
        String controllerPackage = properties.getProperty("controllerPackage");
        boolean annotatedMapper = "ANNOTATEDMAPPER".equals(context.getJavaClientGeneratorConfiguration().getConfigurationType().toUpperCase());


        AdditionalProperty additionalProperty = new AdditionalProperty();
        additionalProperty.setEnableSwagger2(enableSwagger2);
        additionalProperty.setEnableSelectSelective(enableSelectSelective);
        additionalProperty.setEnableService(enableService);
        additionalProperty.setServiceTargetProject(serviceTargetProject);
        additionalProperty.setServicePackage(servicePackage);
        additionalProperty.setServiceImplTargetProject(serviceImplTargetProject);
        additionalProperty.setServiceImplPackage(serviceImplPackage);
        additionalProperty.setEnableController(enableController);
        additionalProperty.setControllerTargetProject(controllerTargetProject);
        additionalProperty.setControllerPackage(controllerPackage);
        additionalProperty.setAnnotatedMapper(annotatedMapper);

        return additionalProperty;
    }

    /**
     * 获取配置的属性并赋值给LombokProperty对象
     *
     * @param properties
     * @param context
     */
    public static LombokProperty setLombokProperty(Properties properties, Context context) {
        Boolean enableLombok = Boolean.valueOf(properties.getProperty("enableLombok", "false"));
        String username = context.getProperty("username");
        String dateTimeFormat = context.getProperty("dateTimeFormat");
        boolean annotatedMapper = "ANNOTATEDMAPPER".equals(context.getJavaClientGeneratorConfiguration().getConfigurationType().toUpperCase());
        LombokProperty lombokProperty = new LombokProperty();
        lombokProperty.setEnableLombok(enableLombok);
        lombokProperty.setUsername(username);
        lombokProperty.setDateTimeFormat(dateTimeFormat);
        lombokProperty.setAnnotatedMapper(annotatedMapper);
        return lombokProperty;
    }


    public static List<BaseMethod> setBaseMethodList() {
        List<BaseMethod> baseMethodList = new ArrayList<>();
        //获取全部的方法类
        Set<Class<?>> classes = ClassScanner.listAllSubclasses("com.yl.plugin.method", BaseMethod.class);

        Streams.stream(classes).forEach(aClass -> baseMethodList.add((BaseMethod) aClass.newInstance()));

        return baseMethodList;
    }


    /**
     * 设置 类上的注解
     *
     * @param tableComment
     * @param context
     */
    public static List<String> setClassComment(String tableComment, Context context) {
        String username = context.getProperty("username");
        String dateTimeFormat = context.getProperty("dateTimeFormat");
        List<String> list = new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        list.add("/**");
        list.add(" * " + tableComment.replace("表", ""));
        list.add(" * ");
        list.add(" * @author " + username);
        list.add(" * @date " + new SimpleDateFormat(dateTimeFormat).format(new Date()));
        list.add(" */");

        return list;
    }

    /**
     * 设置字段注释
     *
     * @param fieldComment
     * @return
     */
    public static List<String> setFieldComment(String fieldComment) {
        List<String> list = new ArrayList<>();
        list.add("/**");
        list.add(" * " + fieldComment);
        list.add(" */");
        return list;
    }

    /**
     * 下划线命名转为驼峰
     *
     * @param name 变量名
     */
    public static String underlineToCamel(String name) {
        if (StringUtils.isBlank(name) || !name.contains("_")) {
            return name;
        }

        String result = "";
        String[] array = name.split("_");
        for (int i = 0; i < array.length; i++) {
            if (i == 0) {
                result += array[i];
            } else {
                result += StringUtils.capitalize(array[i]);
            }
        }
        return result;
    }

    /**
     * 列表转为字符串并按指定数换行
     *
     * @param list
     * @param joint 拼接符
     * @param n     几个元素拼接换行
     * @param line   换行符
     * @return
     */
    public static String strAndNewLine(List<String> list, String joint, int n, String line) {
        Objects.requireNonNull(list, "列表不能为空");
        Objects.requireNonNull(joint, "拼接符不能为空");
        if (list.isEmpty()) {
            return "";
        }
        if (n < 1 || n >= list.size()) {
            return list.stream().collect(Collectors.joining(joint));
        }

        int length = list.size();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            sb.append(list.get(i)).append(joint);
            if ((i + 1) % n == 0) {
                sb.append(line);
            }
        }

        return sb.substring(0, sb.length() - joint.length());
    }
}
